package com.swipemaster.common;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.util.SparseArray;

import com.swipemaster.R;

public class Bitmaps
{
	/** Circular bitmaps. */
	public static Bitmap playerBitmap;
	public static Bitmap enemyBitmap;
	public static Bitmap alphaEnemyBitmap;
	public static Bitmap angryEnemyBitmap;
	public static Bitmap alphaAngryEnemyBitmap;
	/** Tiles for repeating backgrounds. */
	public static Bitmap finishTile;
	public static Bitmap wallTile;
	/** Background during the game play. */
	public static Bitmap gameBg;
	/** Background for high scores. */
	public static BitmapDrawable highScoresBg;
	/** Options for loading bitmaps. */
	private final static BitmapFactory.Options opts = new BitmapFactory.Options();
	private final static int ALPHA = 160;
	private final static Config PIXEL_FORMAT = Config.ARGB_8888;
	/** Bitmaps cache. Thanks to this Bitmaps are reused. */
	private final static int MAX_NUMBER_OF_BITMAPS = 50;
	private final static SparseArray<Bitmap> bitmapCache = new SparseArray<Bitmap>(MAX_NUMBER_OF_BITMAPS);

	static
	{
		opts.inPreferredConfig = PIXEL_FORMAT;
	}

	public static Bitmap createBitmap(int resId)
	{
		return BitmapFactory.decodeResource(Global.app.getResources(), resId, opts);
	}

	public static Bitmap getScaledBitmap(int width, int height, Bitmap bitmap)
	{

		final int key = getKey(width, height, bitmap);
		Bitmap scaledBitmap = bitmapCache.get(key);
		if (scaledBitmap == null)
		{
			scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
			bitmapCache.put(key, scaledBitmap);
		}
		return scaledBitmap;
	}

	public static Bitmap getTiledBitmap(int width, int height, Bitmap tile)
	{
		final int key = getKey(width, height, tile);
		Bitmap tiledBitmap = bitmapCache.get(key);
		if (tiledBitmap == null)
		{
			tiledBitmap = Bitmap.createBitmap(width, height, PIXEL_FORMAT);
			final Canvas canvas = new Canvas(tiledBitmap);
			final Shader shader = new BitmapShader(tile, TileMode.REPEAT, TileMode.REPEAT);
			final Paint paint = new Paint();
			paint.setShader(shader);
			canvas.drawPaint(paint);
			bitmapCache.put(key, tiledBitmap);
		}
		return tiledBitmap;
	}

	public static void load()
	{
		playerBitmap = createBitmap(R.drawable.happy_green);
		enemyBitmap = createBitmap(R.drawable.bored_red);
		alphaEnemyBitmap = addAlpha(enemyBitmap);
		angryEnemyBitmap = createBitmap(R.drawable.angry_red2);
		alphaAngryEnemyBitmap = addAlpha(angryEnemyBitmap);
		finishTile = createBitmap(R.drawable.finish);
		wallTile = createBitmap(R.drawable.wall2);
		gameBg = createBitmap(R.drawable.my_background_small);
		highScoresBg = new BitmapDrawable(createBitmap(R.drawable.achievements));
	}

	private static Bitmap addAlpha(Bitmap bitmap)
	{
		final Bitmap result = bitmap.copy(PIXEL_FORMAT, true);
		final Canvas canvas = new Canvas(result);
		final int alphaColor = ALPHA << 24;
		canvas.drawColor(alphaColor, PorterDuff.Mode.DST_IN);
		return result;
	}

	private static int getKey(int width, int height, Bitmap bitmap)
	{
		final int MAXIMUM_WIDTH = 1013;
		return bitmap.hashCode() + width + (MAXIMUM_WIDTH * height);
	}
}
